﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Windows.Forms;
using System.Net;
using ChatClientApp.Tools;
using System.IO;
using ChatClientApp.Classes;

namespace ChatClientApp.GUI
{
    public partial class fChatWindow : Form
    {
        string contactUserName;
        IPEndPoint contactEndpoint;
        public delegate void DelegateChatWindow_Load(object sender, EventArgs e);
        
        public fChatWindow()
        {
            InitializeComponent();
            Font font = richTextBox1.Font;
            Font f = new Font(font.FontFamily, font.Size + 2f);
            richTextBox1.Font = f;
            richTextBox2.Focus();
        }

        public void Initialize(string username)
        {
            ActiveComponents.ActiveContactChat.Add(username);
            ActiveComponents.ActiveContactChatWindow.Add(this);
            this.contactUserName = username;
            requestClientIp(this.contactUserName);
            this.Text = username;
        }

        private void ChatWindow_Load(object sender, EventArgs e)
        {
            if (!InvokeRequired)
            {
                ActiveComponents.ActiveContactChat.Add(this.Text);
                ActiveComponents.ActiveContactChatWindow.Add(this);
                this.contactUserName = this.Text;
                requestClientIp(this.contactUserName);
                if (contactEndpoint == null)
                {
                    richTextBox1.SelectionColor = Color.Red;
                    Font oldFont = richTextBox1.SelectionFont;
                    richTextBox1.SelectionFont = new Font("Verdana", 10F, FontStyle.Bold, GraphicsUnit.Point);
                    richTextBox1.AppendText("User is offline");
                    richTextBox1.SelectionColor = Color.Black;
                    richTextBox1.SelectionFont = oldFont;
                    button1.Enabled = false;
                    richTextBox2.Focus();
                }
                else
                {
                    button1.Enabled = true;
                    richTextBox2.Focus();
                }
            }
            else
            {
                Invoke(new DelegateChatWindow_Load(ChatWindow_Load), new object[] {sender,e});
            }
        }

        private void ChatWindow_FormClosed(object sender, FormClosedEventArgs e)
        {
            ActiveComponents.ActiveContactChat.Remove(this.Text);
            ActiveComponents.ActiveContactChatWindow.Remove(this);
        }

        private void button1_Click(object sender, EventArgs e)
        {
            List<string> msg = new List<string>();
            msg.Add(ActiveComponents.ActiveUser.Nick + ": ");
            richTextBox1.SelectionColor = Color.Red;

            richTextBox1.AppendText(msg.ElementAt(0) + Tools.Tools.NL);
            richTextBox1.SelectionColor = Color.Black;

            foreach (string element in richTextBox2.Lines)
            {
                // richTextBox1.AppendText(element + Tools.Tools.NL);
                msg.Add(element);
            }

            string temp = msg.ElementAt(0);
            msg.RemoveAt(0);
            AddMessage(msg.ToArray());
            msg.Insert(0, temp);
            richTextBox1.AppendText(Tools.Tools.NL);

            richTextBox2.Lines = new String[] { "" };

            try
            {
                ActiveComponents.ListenServer.sendMessage(contactEndpoint, ActiveComponents.ActiveUser.Nick, msg.ToArray());
                // ActiveComponents.ListenServer.sendMessage(contactEndpoint, ActiveComponents.ActiveUser.Nick, message);
            }
            catch (Exception ex)
            {
                richTextBox1.AppendText("Client probably offline...");
            }
        }

        private void requestClientIp(string Client)
        {
            try
            {
                contactEndpoint = ServerHandling.RequestUserIP(Client);
            }
            catch (Exception e)
            {
            }
        }

        public void AddMessage(string[] message)
        {

            // String[] tempMessage = message.ToAsciiString("NEWLINE");
            for (int i = 0; i < message.Length; i++)
            {
                string tempMessage = message[i];

                while (tempMessage.Contains(":)"))
                {
                    richTextBox1.AppendText(tempMessage.Substring(0, tempMessage.IndexOf(":)")));
                    addImage(":)");
                    tempMessage = tempMessage.Substring(tempMessage.IndexOf(":)") + 2);
                }

                richTextBox1.AppendText(tempMessage + Tools.Tools.NL);
                /*
                if (message[i].Contains(":)"))
                {
                    
                    string tempMessage2 = message[i].Substring(message[i].IndexOf(":)") + 1);
                    richTextBox1.AppendText(tempMessage);
                    // TODO: here add smileys
                    addImage(":)");

                    richTextBox1.AppendText(tempMessage);
                }
                */
                // richTextBox1.AppendText(message[i] + Tools.Tools.NL);
            }

            // richTextBox1.AppendText(Tools.Tools.NL);
            richTextBox1.ScrollToCaret();
        }

        public void AddMessage(string[] message, IPEndPoint EndPoint)
        {
            richTextBox1.SelectionColor = Color.Green;
            richTextBox1.AppendText(message[0] + Tools.Tools.NL);
            richTextBox1.SelectionColor = Color.Black;

            List<string> los = message.ToList();
            los.Add(String.Empty);
            los.RemoveAt(0);
            message = null;
            message = los.ToArray();

            AddMessage(message);
        }

        private void richTextBox2_KeyPress(object sender, KeyPressEventArgs e)
        {
            int eKey = (int)e.KeyChar;
            int kKey = (int)Keys.Enter - 3;
            if ((Control.ModifierKeys == Keys.Control) && (eKey == kKey))
            {
                this.richTextBox2.Text = this.richTextBox2.Text.Remove(richTextBox2.Text.LastIndexOf("\n"));
                this.button1_Click(sender, new EventArgs());
            }
        }

        private void verlaufSpeichernToolStripMenuItem_Click(object sender, EventArgs e)
        {
            try
            {
                SaveFileDialog sfd = new SaveFileDialog();
                sfd.InitialDirectory = Directory.GetCurrentDirectory() + "\\History";
                sfd.FileName = this.Text + "_" + DateTime.Now.Year.ToString() + "_" + DateTime.Now.Month.ToString() + "_" + DateTime.Now.Day.ToString();
                sfd.DefaultExt = ".rtf"; ;
                sfd.Filter = "RTF Dateien|*.rtf|Text Dateien|*.txt|Log Dateien|*.log|Alle Dateien|*.*";

                if (!(Directory.Exists(sfd.InitialDirectory)))
                {
                    Directory.CreateDirectory(sfd.InitialDirectory);
                }

                if (sfd.ShowDialog() == DialogResult.OK)
                {
                    if (sfd.FileName.Substring(sfd.FileName.IndexOf(".")+1) == "rtf")
                        File.WriteAllText(sfd.FileName, richTextBox1.Rtf);
                    else
                        File.WriteAllLines(sfd.FileName, richTextBox1.Lines);
                    
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("Datei konnte nicht gesschrieben werden." + Tools.Tools.NL +
                                "" + Tools.Tools.NL +
                                ex.Message , "Error");
            }

        }

        private void dateiVersendenToolStripMenuItem_Click(object sender, EventArgs e)
        {
            OpenFileDialog ofd = new OpenFileDialog();
            ofd.InitialDirectory = Directory.GetCurrentDirectory();
            ofd.Filter = "Alle Dateien|*.*";
            if (ofd.ShowDialog() == DialogResult.OK)
            {
                try
                {
                    ActiveComponents.ListenServer.sendFile(ActiveComponents.ActiveUser.Nick, ofd.FileName, contactEndpoint);
                    richTextBox1.SelectionColor = Color.Red;
                    richTextBox1.AppendText(ActiveComponents.ActiveUser.Nick + ": " + Tools.Tools.NL);
                    richTextBox1.SelectionColor = Color.Black;
                    richTextBox1.AppendText("File: " + ofd.FileName + " send..." + Tools.Tools.NL + Tools.Tools.NL);
                }
                catch (Exception ex)
                {
                    richTextBox1.AppendText("Client probably offline...");
                }
            }
        }

        public void AddFileMessage(ChatFileMessage fMsg)
        {
            AddMessage(fMsg.Message, fMsg.Ip);

            if (MessageBox.Show("File received. Save?", "File received.", MessageBoxButtons.YesNo) == DialogResult.Yes)
            {
                SaveFileDialog sfd = new SaveFileDialog();
                sfd.InitialDirectory = Directory.GetCurrentDirectory();
                sfd.Filter = "Alle Dateien|*.*";
                sfd.FileName = fMsg.FileName;
                if (sfd.ShowDialog() == DialogResult.OK)
                {
                    BinaryWriter bw = new BinaryWriter(File.Create(sfd.FileName));
                    bw.Write(fMsg.FileData);
                    bw.Close();

                    // File.WriteAllBytes(sfd.FileName, fMsg.FileData);
                }
            }
        }

        private void addImage(string caseImage)
        {
            switch (caseImage)
            {
                case ":)":
                    insertImage(ChatClientApp.Properties.Resources._smile_);
                    break;
                default:
                    break;
            }
        }

        private void insertImage(Image image)
        {
            image = Tools.Tools.resizeImage(image, new Size(14,14));
            bool isImage = false;
            bool isText = false;
            object temp = storeClipBoardStuff(out isText, out isImage);

            Clipboard.SetDataObject(image);
            DataFormats.Format format = DataFormats.GetFormat(DataFormats.Bitmap);

            if (richTextBox1.CanPaste(format))
                richTextBox1.Paste(format);
            else
            {
                richTextBox1.ReadOnly = false;
                richTextBox1.Paste(format);
                richTextBox1.ReadOnly = true;
            }

            if (isImage)
                Clipboard.SetImage((Image)temp);
            else if (isText)
                Clipboard.SetText((string)temp);
        }

        private object storeClipBoardStuff(out bool isString, out bool isImage)
        {
            object ret = null;

            if (Clipboard.ContainsText())
            {
                ret = (object)Clipboard.GetText();
                isString = true;
                isImage = false;
            }
            else if (Clipboard.ContainsImage())
            {
                ret = (object)Clipboard.GetImage();
                isString = false;
                isImage = true;
            }
            else
            {
                Clipboard.Clear();
                isString = false;
                isImage = false;
            }
            return ret;
        }
    }
}
